﻿using System;
using System.Collections.Generic;
using System.Linq;
//using System.Threading;
using System.Timers;

namespace UtilityToolsCollect.ObjectsLibrary.ProcessManage
{
    /// <summary>
    /// 在有进程数量限制的条件下，先判断当前运行的进程数是否达到限制，
    /// 根据处理器空闲率，判断是否有余力开始下一个进程
    /// </summary>
    public class DefaultProcesMangeSchedule : ProcesMangeScheduleAbstract,IDisposable
    {
        Timer timer;
        CpuPerformanceCount TotalCpuIdle;
        bool IsEnableMaxCPUThreadLimit;
        int MaxCPUThread;
        

        public DefaultProcesMangeSchedule(IProcessManage manage, double IntervalTime = 10000, bool EnableMaxCPUThreadLimit = true, int maxCPUThread = 6) : base(manage)
        {
            IsEnableMaxCPUThreadLimit = EnableMaxCPUThreadLimit;
            MaxCPUThread = maxCPUThread;
            timer = new Timer(IntervalTime);
            timer.Elapsed += (s, e) => ScheduleNext();
            timer.AutoReset = true;
            timer.Enabled = false;
            TotalCpuIdle = CpuPerformanceCount.Create(CpuPerformanceCount.PerformanceCountTypeEnum.Idle);
            _ = TotalCpuIdle.Value;
        }

        public override bool IsRunning => timer.Enabled;

        public override void ScheduleNext()
        {
            IEnumerable<ProcessShell> shells = Manage.ShellList.Where(p => p.IsRunning);
            int RunCount = shells.Count();
            if (IsEnableMaxCPUThreadLimit &&  RunCount >= MaxCPUThread) 
                return;

            if ((shells.Sum(p => p.ProcessWeightedAverageValue) / RunCount) + 7 < TotalCpuIdle.Value)
                Manage.Next();
        }

        public override void StartRunning()=>timer.Start();

        public override void Stop() => timer.Stop();

        protected override void OnDispose()
        {
            if (TotalCpuIdle != null)
            {
                TotalCpuIdle.Dispose();
                TotalCpuIdle = null!;
            }
            if (timer != null)
            {
                if (timer.Enabled)
                    timer.Stop();
                timer.Dispose();
                timer = null!;
            }
        }

    }
}
